package com.tjetc;

import java.io.Serializable;

/**
 * 双重检查锁
 */
public class DclSingleton implements Serializable {
    // 创建对象，不是一个原子性操作。半初始化状态
    // volatile 1.保证内存可见性 2.保证有序性 可以保证原子性操作
    // volatile如果不加可能会出现半初始化的对象
    // 现在用的高版本的 Java 已经在 JDK 内部实现中解决了这个问题（解决的方法很简单，
    // 只要把对象 new 操作和初始化操作设计为原子操作，就自然能禁止重排序）,为了兼容性我们加上
    // 1.创建静态变量，但是不创建实例
    private static volatile DclSingleton instance;

    // 2.构造方法私有化
    private DclSingleton() {
        // 防止反射入侵
        // 一定先执行getInstance方法后才会存在实例
        if (instance != null) {
            throw new RuntimeException("实例已经创建了");
        }
    }

    //3. 暴露一个获取实例的方法
    public static DclSingleton getInstance() {
            if (instance == null) {
                // 阻塞停在这里，等待锁 创建多个对象
                synchronized (DclSingleton.class) {
                    if (instance == null) {
                        instance = new DclSingleton();
                    }
            }
        }
        return instance;
    }

    /**
     * 当反序列化的时候，对象不会被克隆一个新的实例返回的还是原有实例
     * @return
     */
    public Object readResolve() {
        return instance;
    }
}
